#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <wait.h>

/**
 * 创建一个子进程
 * @return
 */
//int main() {
//    // 创建一个子进程
//    fork();
//    printf("Hello, World!\n");
//    return 0;
//}

/**
 * 区分 父子 进程
 * @return
 */
//int main() {
//
//    pid_t  pid = -1;
//    // 创建一个子进程 在子进程中返回 0 ，在 父进程中返回 子进程的 pid
//    pid = fork();
//    if(0 == pid){
//        printf("hello child pid=%d ppid=%d\n",getpid(),getppid());
//        exit(0);
//    }
//    else {
//        printf("parent child pid=%d cpid=%d\n",getpid(),pid);
//    }
//    return 0;
//}

/**
 * 父子 进程 地址空间 读时共享，写时拷贝 数据地址都是一样的
 * valgrind ./a.out 查看内存泄露
 * @return
 */
//全局变量在数据段中
//int num = 100;
//int main() {
//    // 栈空间中
//    int var = 44;
//    int * p = NULL;
//    // 堆空间中
//    p = malloc(sizeof(int));
//    if(NULL == p){
//        return 1;
//    }
//    memset(p,0, sizeof(int));
//    *p = 200;
//    pid_t  pid = -1;
//    // 创建一个子进程 在子进程中返回 0 ，在 父进程中返回 子进程的 pid
//    pid = fork();
//    if(-1 == pid){
//        perror("fork");
//        return 1;
//    }
//    if(0 == pid){
//        printf("子进程之前 var = %d num = %d *p =%d\n",var,num,*p);
//        sleep(3);
//        printf("子进程之后 var = %d num = %d *p =%d\n",var,num,*p);
//
//    }
//    else {
//        printf("父进程之前 var = %d num = %d *p =%d\n",var,num,*p);
//        sleep(1);
//        var ++ ;
//        num ++ ;
//        (*p) ++;
//        printf("父进程之后 var = %d num = %d *p =%d\n",var,num,*p);
//    }
//    free(p);
//    p = NULL;
//    return 0;
//}

/**
 * 进程退出
 * @return
 */
//int main() {
//    printf("hello world!");
//    //等价于 return 0
//    //exit(0);
//
//    //直接退出不做任何其他的处理 等价于 _Exit(0)
//    _exit(0);
//    //return 0;
//}

/**
 * wait waitpid
 * 子进程 最后会变成 孤儿进程 : 暂时定义为没有危险
 * 僵尸进程： 子进程结束后，父进程并没有处理回收资源，危害大，程序不应该有僵尸进程
 * @return
 */
//int main() {
//    pid_t pid = -1;
//    int i = 0;
//    int status = 0;
//    int ret = -1;
//    pid = fork();
//    if(-1 == pid){
//        perror("fork");
//        return 1;
//    }
//    if(0 == pid){
//        for (i = 0; i < 5; ++i) {
//            printf("child process run %d  ppid %d\n",i,getppid());
//            sleep(1);
//        }
//        exit(10);
//    }
//    printf("parent process wait\n");
//    // 父进程阻塞等待 子进程退出
//    //wait(&status);
//
//    // 等价于wait
//    //ret = waitpid(-1,&status,0);
//    //                                          表示不阻塞
//    ret = waitpid(-1,&status,WNOHANG);
//
//    printf("resource get back!\n");
//    // 进程正常结束
//    if(WIFEXITED(status)){
//        //                                                  获取进程退出状态（exit的参数）
//        printf("child normal exit status code %d\n", WEXITSTATUS(status));
//    }
//    // 进程异常终止
//    else if(WIFSIGNALED(status)){
//        //                                                 获取进程终止的信号编号
//        printf("child error exit status code %d\n", WTERMSIG(status));
//    }
//    // 进程处于暂停状态
//    else if(WIFSTOPPED(status)){
//        //                                           获取使得进程暂停的那个信号的编号
//        printf("child wait status code %d\n", WIFCONTINUED(status));
//    }
//    return 0;
//}

/**
 * 进程替换
 * @return
 */
int main(){
    printf("hello\n");
    //arg0,arg1,arg2 ... argn
    //arg0一般为可执行文件名,argn必须时NULL
    //等价于ls -l /home
    //execlp("ls","ls","-l","/home",NULL);
    //          绝对路径或者相对路径 可执行文件名称 可执行文件的选项参数 最后一定时NULL结束
    execl("/bin/ls","ls","-l","/home",NULL);
    // 不会被打印出来
    printf("world\n");
}